package LeeJS;

public class J26_TypeCasting {
	
	/*
			
			모든 클래스는 자동적으로 java.lang.Object를 확장함
			즉, Object 클래스는 자바에서 궁극의 super 클래스임
			기본적으로 Object 클래스에는 7개의 메서드가 정의되어 있고, 
			하위 클래스에서는 이것을 재정의해서 적절히 사용 가능
			equals - 기존 객체와 매개변수로 전달된 객체와 비교 객체 
					  비교가 재대로 이뤄질려면 메서드를 재정의하고 구현해야 함
			hashcode - 객체의 해시코드를 출력함
					       객체는 일반적으로 heap에 생성됨
					   heap에 생성된 객체의 메모리 주소를 
					       바탕으로 만들어지는 유일한 코드값을 의미
			toString - 객체에 대한 설명을 출력함
			
			다형성 polymorphism
			OOP 의 중요 개념 중 하나
			특정 유형의 프로그래밍 요소(변수)가 상황에 따라
			다양한 유형의 변수로 바뀔 수 있는 특성을 의미
			주로 상속관계에 있는 클래스간에서 나타나는 성질
			
			is-a 관계확인
			특정 객체가 어떤 유형과 동일한지 또는 상속 관계인지 알아볼때 instanceof 예약어를 사용
			
			
	 */
	
	public static void main(String[] args) {
		
		Object obj = new Object();
		
		J25_Animal a = new J25_Animal();
		
		J25_Fish b = new J25_Fish();
		
		a = new J25_Fish();
		
		/*
		
				Fish 는 Animal 를 확장했기 때문에 Animal 객체에 Fish 객체를 받을 수 있음
				하위 객체를 상위 객체로 cast 하는 경우 이것을 upcasting 이라 함
				
		*/
		
		//b = (J25_Fish) new J25_Animal();
				//상위 객체를 하위 객체로 cast 하는 경우 이것을 downcasting 이라 함
				//이때 명시적 괄호안에 cast 할 클래스 자료형을 명시
		
		
		//스타크래프트 게임내에서 해병, 불곰, 의무병을 생산하는 경우
		
		
		Marine m1 = new Marine();
		
		Firebat f1 = new Firebat();
		
		Medic d1 = new Medic();
		
		//다향성을 근거로 테란유닛 생산(upcasting)
		//즉, Marine 유닛은 상황에 따라 TerranUnits 도 될 수 있다는 의미
		TerranUnits t1 = new Marine();		//upcasting
		t1.sayUnit();
		t1.sayUnit((Marine)t1);				//downcasting
		TerranUnits t2 = new Firebat();
		t1.sayUnit();
		t1.sayUnit((Firebat)t2);	
		TerranUnits t3 = new Medic();
		t1.sayUnit();
		t1.sayUnit((Medic)t3);
		
		//AllianceUnit - Human, Wolf, Nom
		
		
		
		
		
		
		//객체 유형 확인하기
		J26_TypeCasting t = new J26_TypeCasting();
		if(t instanceof java.lang.Object){
			System.out.println("t 는 Object 의 자손");
		}
		
		if(m1 instanceof java.lang.Object){
			System.out.println("해병은 테란유닛의 자손");
		}
		
		if(m1 instanceof TerranUnits){				//is - a
			System.out.println("해병은 테란유닛의 자손");
		}
		if(m1 instanceof Marine){
			System.out.println("m1은 해병임");			//동질성
		}
		
	}
	
	
}

//테란 유닛 - 마린, 파벳, 메딕

class TerranUnits{
	String 이름;
	String 쉴드;
	int 생명력;
	int 에너지;
	int 방어력;
	int 광물;
	int 베스핀;
	int 보급품;
	int 사거리;
	int 생산시간;
	int 공격력;
	
	public void sayUnit(){
		
		System.out.println("저는 테란입니다");
		
	}
	public void sayUnit(Marine m){
		
		System.out.println("저는 마린입니다");
		
	}
	public void sayUnit(Firebat f){
		
		System.out.println("저는 파벳입니다");
		
	}
	public void sayUnit(Medic d){
		
		System.out.println("저는 메딕입니다");
		
	}
	
	public TerranUnits(){}
	
	
	public TerranUnits(String 이름, String 쉴드, int 생명력, int 방어력, int 에너지, int 공격력, int 광물, int 베스핀, int 보급품, int 사거리, int 생산시간){
		
		this.이름 = 이름;
		this.쉴드 = 쉴드;
		this.생명력 = 생명력;
		this.방어력 = 방어력;
		this.에너지 = 에너지;
		this.공격력 = 공격력;
		this.방어력 = 방어력;
		this.광물 = 광물;
		this.베스핀 = 베스핀;
		this.보급품 = 보급품;
		this.사거리 = 사거리;
		this.생산시간 = 생산시간;
		
		
	}
	
	
	
	
}

class Marine extends TerranUnits{
	
	
	
}
class Firebat extends TerranUnits{
	
	
	
}
class Medic extends TerranUnits{
	
	
	
}